package com.shigen.file.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shigen.file.common.Result;
import com.shigen.file.entity.Project;
import com.shigen.file.entity.ProjectData;
import com.shigen.file.exception.BusinessException;
import com.shigen.file.mapper.ProjectDataMapper;
import com.shigen.file.service.IProjectDataService;
import com.shigen.file.service.IProjectService;
import com.shigen.file.util.IPUtil;
import com.shigen.file.util.TimeUtil;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 表单的数据 服务实现类
 * </p>
 *
 * @author shigen.fu
 * @since 2022-06-04
 */
@Service
@Slf4j
public class ProjectDataServiceImpl extends ServiceImpl<ProjectDataMapper, ProjectData> implements IProjectDataService {

  @Resource
  private IProjectService projectService;

  @Override
  public IPage<ProjectData> getProjectData(String projId, IPage<ProjectData> page) {
    LambdaQueryWrapper<ProjectData> queryWrapper = Wrappers.<ProjectData>lambdaQuery().eq(StrUtil.isNotEmpty(projId), ProjectData::getProjId, projId)
        .eq(ProjectData::getIsDel, 0);
    return getBaseMapper().selectPage(page, queryWrapper);
  }

  /**
   * 获得表单数据
   */
  @Override
  public IPage<JSONObject> getProjectData(String projId, Boolean withAdditionInfo, IPage<ProjectData> page) {
    IPage<ProjectData> dataPage = this.getProjectData(projId, page);
    List<ProjectData> projectData = dataPage.getRecords();
    List<JSONObject> jsonObjects = new ArrayList<>();
    projectData.forEach(data -> {
      JSONObject jsonObject = new JSONObject();
      if (withAdditionInfo) {
        jsonObject.put("id", data.getAutoId());
        jsonObject.put("表单id", data.getProjId());
        jsonObject.put("ip", data.getIp());
        jsonObject.put("设备码", data.getMurmur());
        jsonObject.put("填写位置", data.getPosition());
        jsonObject.put("操作系统", data.getOs());
        jsonObject.put("浏览器", data.getBrowser());
        jsonObject.put("填写用时", TimeUtil.formatSec(data.getTimeUse() == 0 ? 0 : data.getTimeUse() / 1000));
        jsonObject.put("提交时间", DateUtil.formatDateTime(data.getCreateTime()));
      }
      // 将json数据存放到jsonObject中
      // {"radio": "Option 3", "select": "Option 3", "wenben": "324242"}
      String jsonData = (String) data.getData();
      try {
        LinkedHashMap linkedHashMap = JSONObject.parseObject(jsonData, LinkedHashMap.class);
        jsonObject.putAll(linkedHashMap);
      } catch (Exception e) {
        log.error("{} 解析错误", jsonData);
      }
      jsonObjects.add(jsonObject);
    });

    Page<JSONObject> resultPage = new Page<>(dataPage.getCurrent(), dataPage.getSize(), dataPage.getTotal());
    resultPage.setRecords(jsonObjects);
    return resultPage;
  }

  @Override
  public Result addProjectData(String projId, Object data, String murmur, Long timeUsed, HttpServletRequest request) {
    Project project = projectService.getProjectById(projId);
    if (project == null) {
      throw new BusinessException("表单不存在");
    }
    // 验证表单时间
    Result<String> stringResult = this.verifyDate(project.getBeginTime(), project.getEndTime());
    if (stringResult != null) {
      return stringResult;
    }
    // 插入数据
    String ip = IPUtil.getIp(request);
    String userAgentStr = request.getHeader("User-Agent");
    UserAgent userAgent = UserAgentUtil.parse(userAgentStr);

    ProjectData projectData = new ProjectData().setProjId(projId)
        .setIp(ip)
        .setMurmur(murmur)
        .setPosition(IPUtil.getCityInfoStr(ip))
        .setData(data)
        .setOs(userAgent.getOs().toString())
        .setBrowser(userAgent.getBrowser().toString())
        .setTimeUse(timeUsed)
        .setCreateTime(new Date())
        .setIsDel(0);
    int insert = getBaseMapper().insert(projectData);
    return insert > 0 ? Result.success("已成功提交，谢谢参与") : Result.err("提交失败，请联系管理员");
  }

  /**
   * 验证当前的时间是否在开始时间和结束时间之间
   */
  Result<String> verifyDate(Date beginTime, Date endTime) {
    Date now = DateUtil.date();
    if (DateUtil.between(beginTime, now, DateUnit.SECOND) <= 0) {
      return Result.err("该表单还未开始收集");
    }
    if (DateUtil.between(endTime, now, DateUnit.SECOND) < 0) {
      return Result.err("该表单已经停止收集");
    }
    return null;
  }
}
